﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ServiceHandler.cs" company="Anton Frattaroli">
//   Copyright (c) Anton Frattaroli. All rights reserved.
// </copyright>
// <summary>
//   Defines the ServiceHandler class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Lidocaine.Service
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Resources;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Web;
    using Ionic.Zip;
    using Lidocaine.BusinessLogic;
    using Lidocaine.BusinessObjects;

    /// <summary>
    /// The ServiceHandler class.
    /// </summary>
    public class ServiceHandler : IHttpHandler
    {
        #region Properties
        /// <summary>
        /// Gets a value indicating whether or not the IHttpHandler implementation is reusable.
        /// </summary>
        public bool IsReusable
        {
            get { return false; }
        }
        #endregion

        #region Utility and Implemetation Methods
        /// <summary>
        /// Processes HTTP requests.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        public void ProcessRequest(HttpContext context)
        {
            ////Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
            context.Response.ContentType = "text/plain";
            Dictionary<string, Action<HttpContext>> dic = this.GetHandlers();
            if (dic.ContainsKey(context.Request.QueryString["f"]))
            {
                dic[context.Request.QueryString["f"]].Invoke(context);
            }
            else
            {
                context.Response.Write(Strings.ServiceNotFound);
            }
        }

        /// <summary>
        /// Cleans up strings for sending as JSON.
        /// </summary>
        /// <param name="value">The string to clean.</param>
        /// <returns>A string ready to be placed as a JSON value.</returns>
        private static string EscapeJson(string value)
        {
            return value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", string.Empty);
        }
        #endregion

        #region FileType
        /// <summary>
        /// Handles the request to delete a hosted file type.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void DeleteFileType(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add(Strings.FileTypeDeleteFailBadUser + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int fileTypeId = 0;
            if (!int.TryParse(context.Request["filetypeID"], out fileTypeId))
            {
                output.Add(Strings.FileTypeDeleteFailBadId);
            }

            if (output.Count == 0)
            {
                FileType fileType = FileTypeManager.GetFileType(fileTypeId);
                List<Asset> files = AssetManager.GetFilesByFileType(fileType);
                if (files.Count == 0)
                {
                    FileTypeManager.Delete(fileType);
                    output.Add(Strings.FileTypeDeleteSuccessful);
                }
                else
                {
                    List<string> dependentFiles = new List<string>();
                    for (int i = 0; i < files.Count; i++)
                    {
                        dependentFiles.Add(files[i].VirtualPath);
                    }

                    output.Add(Strings.FileTypeDeleteFailDependencies + "<ul><li>" + string.Join("</li><li>", dependentFiles.ToArray()) + "</li></ul>");
                }
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to add a hosted file type.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddFileType(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add(Strings.FileTypeInsertFailBadUser + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (!Regex.IsMatch(context.Request["extension"], @"^[\w]+$"))
            {
                output.Add(Strings.FileTypeInsertFailBadExtension);
            }

            FileType f = FileTypeManager.GetFileTypeByExtension(context.Request["extension"]);
            if (f != null)
            {
                output.Add(Strings.FileTypeInsertFailExtensionExists);
            }

            if (output.Count == 0)
            {
                f = new FileType();
                f.Extension = context.Request["extension"].ToLowerInvariant();
                f.Mime = context.Request["mime"].ToLowerInvariant();
                FileTypeManager.SaveAs(f);
                output.Add(Strings.FileTypeInsertSuccessful);
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to update a hosted file type.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdateFileType(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add(Strings.FileTypeUpdateFailBadUser + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int fileTypeId = 0;
            if (!int.TryParse(context.Request["filetypeID"], out fileTypeId))
            {
                output.Add(Strings.FileTypeUpdateFailBadId);
            }

            if (output.Count == 0)
            {
                FileType f = FileTypeManager.GetFileType(fileTypeId);
                f.Mime = context.Request["mime"].ToLowerInvariant();
                FileTypeManager.Save(f);
                output.Add(Strings.FileTypeUpdateSuccessful);
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to select all hosted file types.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void LoadFileTypes(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add(Strings.FileTypeSelectFailBadUser + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<FileType> filetypes = FileTypeManager.GetFileTypes();
                for (int i = 0; i < filetypes.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{\"FileTypeID\" : \"{0}\",\"Extension\" : \"{1}\",\"Mime\" : \"{2}\"}}", filetypes[i].Id, EscapeJson(filetypes[i].Extension), EscapeJson(filetypes[i].Mime)));
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }
        #endregion

        #region PageLayout Settings
        /// <summary>
        /// Handles the request to update a page's title.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsTitle(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    p.Title = context.Request["title"];
                    PageLayoutManager.Save(p);
                    context.Response.Write("Page title update successful.");
                }
                else
                {
                    context.Response.Write("Page title update failed: Page identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page title update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's header.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsHeader(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int headerId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["headerID"]) && int.TryParse(context.Request["headerID"], out headerId))
                    {
                        p.Header = TemplateManager.GetTemplate(headerId);
                    }
                    else
                    {
                        p.Header = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Header Update Saved.");
                }
                else
                {
                    context.Response.Write("Page header update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page header update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's footer.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsFooter(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int footerId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["footerID"]) && int.TryParse(context.Request["footerID"], out footerId))
                    {
                        p.Footer = TemplateManager.GetTemplate(footerId);
                    }
                    else
                    {
                        p.Footer = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Footer Update Saved.");
                }
                else
                {
                    context.Response.Write("Page footer update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page footer update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's right column.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsRightCol(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int rightColId = 0;
                    if (int.TryParse(context.Request["rightcolID"], out rightColId))
                    {
                        PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                        p.RightCol = TemplateManager.GetTemplate(rightColId);
                        PageLayoutManager.Save(p);
                        context.Response.Write("Page Right Column Update Saved.");
                    }
                }
                else
                {
                    context.Response.Write("Page right column update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page right column update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's left column.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsLeftNav(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int leftNavId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["leftnavID"]) && int.TryParse(context.Request["leftnavID"], out leftNavId))
                    {
                        p.LeftNav = TemplateManager.GetTemplate(leftNavId);
                    }
                    else
                    {
                        p.LeftNav = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Left Column Update Saved.");
                }
                else
                {
                    context.Response.Write("Page left column update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page left column update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's top column.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsTopNav(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int topNavId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["topnavID"]) && int.TryParse(context.Request["topnavID"], out topNavId))
                    {
                        p.TopNav = TemplateManager.GetTemplate(topNavId);
                    }
                    else
                    {
                        p.TopNav = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Top Column Update Saved.");
                }
                else
                {
                    context.Response.Write("Page top column update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Page top column update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's stylesheet.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsCss(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int scriptId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["cssID"]) && int.TryParse(context.Request["cssID"], out scriptId))
                    {
                        p.Css = ScriptManager.GetScript(scriptId);
                    }
                    else
                    {
                        p.Css = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Style Sheet Update Saved.");
                }
                else
                {
                    context.Response.Write("Page stylesheet update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Script update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update a page's javascript.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsJS(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int scriptId = 0;
                    PageLayout p = PageLayoutManager.GetPageLayout(pageId);
                    if (!string.IsNullOrEmpty(context.Request["jsID"]) && int.TryParse(context.Request["jsID"], out scriptId))
                    {
                        p.JavaScript = ScriptManager.GetScript(scriptId);
                    }
                    else
                    {
                        p.JavaScript = null;
                    }

                    PageLayoutManager.Save(p);
                    context.Response.Write("Page Javascript Update Saved.");
                }
                else
                {
                    context.Response.Write("Page script update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("Script update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to update the content version of a page.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdatePageSettingsContentVersion(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    int contentId = 0;
                    if (int.TryParse(context.Request["blockID"], out contentId))
                    {
                        PageLayout page = PageLayoutManager.GetPageLayout(pageId);
                        Content content = ContentManager.GetContent(contentId);
                        if (page != null && content != null && content.PageId == page.Id)
                        {
                            page.Content = content;
                            PageLayoutManager.Save(page);
                            context.Response.Write("Content Version Changed.");
                        }
                    }
                }
            }
            else
            {
                context.Response.Write("Content version update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to select a page's settings.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void EditPageSettings(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
            {
                string pagePath = context.Request["pagePath"];
                string output = string.Empty;
                List<string> jsonHeaders = new List<string>();
                List<string> jsonFooters = new List<string>();
                List<string> jsonCSSs = new List<string>();
                List<string> jsonJSs = new List<string>();
                List<string> jsonTopNavs = new List<string>();
                List<string> jsonRightCols = new List<string>();
                List<string> jsonLeftNavs = new List<string>();
                List<string> jsonVersions = new List<string>();
                PageLayout p = PageLayoutManager.GetPageLayout(pagePath);
                output += string.Format(CultureInfo.InvariantCulture, "\"pID\" : \"{0}\", \"pTitle\" : \"{1}\", \"pHead\" : \"{2}\", \"pFoot\" : \"{3}\", \"pCss\" : \"{4}\", \"pJs\" : \"{5}\", \"pCurrentVersion\" : \"{6}\", \"pTopNav\" : \"{7}\", \"pLeftNav\" : \"{8}\", \"pRightCol\" : \"{9}\"", p.Id, p.Title != null ? p.Title : string.Empty, p.HeaderId, p.FooterId, p.CssId, p.JavaScriptId, p.ContentId, p.TopNavId, p.LeftNavId, p.RightColId);
                Dictionary<int, string> layoutElements = TemplateManager.GetTemplates(TemplateArea.Header);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonHeaders.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = TemplateManager.GetTemplates(TemplateArea.LeftNav);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonLeftNavs.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = TemplateManager.GetTemplates(TemplateArea.TopNav);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonTopNavs.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = TemplateManager.GetTemplates(TemplateArea.Footer);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonFooters.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = ScriptManager.GetScripts(ScriptType.Css);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonCSSs.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = ScriptManager.GetScripts(ScriptType.JS);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonJSs.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                layoutElements = TemplateManager.GetTemplates(TemplateArea.RightCol);
                foreach (KeyValuePair<int, string> kvp in layoutElements)
                {
                    jsonRightCols.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                List<BusinessObjects.Content> contents = PageLayoutManager.GetPageContentVersionsInfo(p);
                for (int i = 0; i < contents.Count; i++)
                {
                    if (contents[i].Author != null)
                    {
                        jsonVersions.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\": \"{0}\", \"CreatedDate\": \"{1}\", \"Author\": \"{2}\"}}", new object[] { contents[i].Id, contents[i].Created, contents[i].Author.UserName }));
                    }
                    else
                    {
                        jsonVersions.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\": \"{0}\", \"CreatedDate\": \"{1}\", \"Author\": \"[Deleted User]\"}}", new object[] { contents[i].Id, contents[i].Created }));
                    }
                }
                
                context.Response.Write("[{ " + output + ", \"Headers\" : [" + string.Join(", ", jsonHeaders.ToArray()) + "], \"Footers\" : [" + string.Join(", ", jsonFooters.ToArray()) + "], \"CSSs\" : [" + string.Join(", ", jsonCSSs.ToArray()) + "], \"JSs\" : [" + string.Join(", ", jsonJSs.ToArray()) + "], \"TopNavs\" : [" + string.Join(", ", jsonTopNavs.ToArray()) + "], \"LeftNavs\" : [" + string.Join(", ", jsonLeftNavs.ToArray()) + "], \"RightCols\" : [" + string.Join(", ", jsonRightCols.ToArray()) + "], \"pVersions\" : [" + string.Join(", ", jsonVersions.ToArray()) + "] }]");
            }
            else
            {
                context.Response.Write("Page settings retrieval failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }
        #endregion

        #region PageLayout Content
        /// <summary>
        /// Handles the request to save the changes made to a page's content and make the new version the current version.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void SaveAndPublishPage(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to update content: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int pageId = 0;
            if (!int.TryParse(context.Request["pageID"], out pageId))
            {
                output.Add("Failed to update content: Invalid pageID parameter.");
            }

            if (output.Count == 0)
            {
                PageLayout page = PageLayoutManager.GetPageLayout(pageId);
                PageLayoutManager.SaveAndPublishContent(page, context.Request["content"], UserProfileManager.Current);
                output.Add("Successfully saved and published page content.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to save the changes made to a page's content.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void SavePage(HttpContext context)
        {
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager") || roles.Contains("Content Provider"))
            {
                int pageId = 0;
                if (int.TryParse(context.Request["pageID"], out pageId))
                {
                    Content content = ContentManager.New();
                    content.Html = context.Request["content"];
                    content.AuthorId = UserProfileManager.Current.Id;
                    content.PageId = pageId;
                    ContentManager.SaveAs(content);
                    context.Response.Write("Page content successfully saved.");
                }
            }
            else
            {
                context.Response.Write("Content update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }

        /// <summary>
        /// Handles the request to select a page's current version content.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void EditPage(HttpContext context)
        {
            bool isAdmin = false;
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (roles.Contains("Site Administrator") || roles.Contains("Content Manager") || roles.Contains("Content Provider"))
            {
                if (roles.Contains("Site Administrator") || roles.Contains("Content Manager"))
                {
                    isAdmin = true;
                }

                PageLayout p = PageLayoutManager.GetPageLayout(context.Request["pagePath"]);
                context.Response.Write("[{ \"IsAdmin\": \"" + (isAdmin ? "1" : "0") + "\", \"PageID\": \"" + p.Id + "\", \"Content\": \"" + (p.Content != null ? EscapeJson(p.Content.Html) : string.Empty) + "\" }]");
            }
            else
            {
                context.Response.Write("Content retrieval failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
        }
        #endregion

        #region DeveloperControls
        /// <summary>
        /// Handles the request to add a main column DeveloperControl.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddMainColumnDeveloperControl(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to register main column DeveloperControl: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            string developerControlName = context.Request["name"];
            if (!Regex.IsMatch(developerControlName, @"^[ \w\.]+$") || string.IsNullOrWhiteSpace(developerControlName))
            {
                output.Add("Failed to register main column DeveloperControl: Please use only alphanumeric characters and spaces. Do not name the DeveloperControl a series of spaces.");
            }

            bool developerControlExists = false;
            List<DeveloperControl> developerControls = DeveloperControlManager.GetDeveloperControls();
            for (int i = 0; i < developerControls.Count; i++)
            {
                if (developerControls[i].Name == developerControlName)
                {
                    developerControlExists = true;
                    break;
                }
            }

            if (developerControlExists)
            {
                output.Add("Failed to register main column DeveloperControl: DeveloperControl already registered.");
            }

            if (output.Count == 0)
            {
                DeveloperControl developerControl = new DeveloperControl();
                developerControl.Name = developerControlName;
                developerControl.Path = context.Request["path"];
                developerControl.Description = context.Request["description"];
                DeveloperControlManager.SaveAs(developerControl);
                output.Add("Successfully registered main column DeveloperControl.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to delete a main column DeveloperControl.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void DeleteMainColumnDeveloperControl(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to remove main column DeveloperControl: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int developerControlId = 0;
            if (!int.TryParse(context.Request["developerControlID"], out developerControlId))
            {
                output.Add("Failed to remove main column DeveloperControl: Invalid developerControlID parameter.");
            }

            if (output.Count == 0)
            {
                DeveloperControl developerControl = DeveloperControlManager.GetDeveloperControl(developerControlId);
                DeveloperControlManager.Delete(developerControl);
                output.Add("Successfully removed main column DeveloperControl.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to select a list of main column DeveloperControls.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void LoadMainColumnDeveloperControls(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load main column DeveloperControls: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<DeveloperControl> m = DeveloperControlManager.GetDeveloperControls();
                for (int i = 0; i < m.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\", \"Path\" : \"{2}\"}}", m[i].Id, m[i].Name, m[i].Path));
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Loads the description of the user control.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadDeveloperControlDescription(HttpContext context)
        {
            int developerControlId = 0;
            if (int.TryParse(context.Request["ID"], out developerControlId))
            {
                DeveloperControl developerControl = DeveloperControlManager.GetDeveloperControl(developerControlId);
                context.Response.Write(developerControl.Description.Replace("\n", "<br />"));
            }
        }

        /// <summary>
        /// Loads user control names and IDs for selection.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadDeveloperControls(HttpContext context)
        {
            List<string> jsonDCs = new List<string>();
            List<DeveloperControl> developerControls = DeveloperControlManager.GetDeveloperControls();
            for (int i = 0; i < developerControls.Count; i++)
            {
                jsonDCs.Add(string.Format(CultureInfo.InvariantCulture, "{{\"DeveloperControlID\" : \"{0}\",\"DeveloperControlName\" : \"{1}\"}}", developerControls[i].Id, developerControls[i].Name));
            }

            context.Response.Write("[" + string.Join(", ", jsonDCs.ToArray()) + "]");
        }
        #endregion

        #region CSS
        /// <summary>
        /// Handles the request to update a style sheet.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdateCss(HttpContext context)
        {
            if (UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                int scriptId = 0;
                if (int.TryParse(context.Request["cssID"], out scriptId))
                {
                    Script s = ScriptManager.GetScript(scriptId);
                    s.ScriptText = context.Request["content"];
                    ScriptManager.Save(s);
                    context.Response.Write("CSS script content successfully updated.");
                }
                else
                {
                    context.Response.Write("Script update failed: Identifier parameter not valid.");
                }
            }
            else
            {
                context.Response.Write("User does not have privileges to save edits to CSS scripts.");
            }
        }

        /// <summary>
        /// Handles the request to select style sheet info for editing.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void EditCss(HttpContext context)
        {
            bool isAdmin = false;
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load CSS: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
            else
            {
                isAdmin = true;
            }

            int scriptId = 0;
            if (!int.TryParse(context.Request["cssID"], out scriptId))
            {
                output.Add("Failed to load CSS: Invalid cssID parameter.");
            }

            if (output.Count == 0)
            {
                Script s = ScriptManager.GetScript(scriptId);
                List<string> pages = ScriptManager.GetPages(s);
                string[] jsonPages = new string[pages.Count];
                for (int i = 0; i < pages.Count; i++)
                {
                    jsonPages[i] = "{\"Name\": \"" + pages[i] + "\"}";
                }

                context.Response.Write("[{ \"IsAdmin\": \"" + (isAdmin ? "1" : "0") + "\", \"Content\": \"" + EscapeJson(s.ScriptText) + "\", \"Pages\" : [" + string.Join(", ", jsonPages) + "]}]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request to add a new style sheet.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddCss(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to create CSS: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to create CSS: Invalid name parameter.");
            }

            Dictionary<int, string> scripts = ScriptManager.GetScripts(ScriptType.Css);
            if (scripts.ContainsValue(context.Request["name"]))
            {
                output.Add("Failed to create CSS: CSS name already exists.");
            }

            if (output.Count == 0)
            {
                Script s = new Script();
                s.Name = context.Request["name"];
                s.ScriptType = ScriptType.Css;
                ScriptManager.SaveAs(s);
                output.Add("Successfully created CSS.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to rename a style sheet.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void RenameCss(HttpContext context)
        {
            string output = string.Empty;
            if (UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                int scriptID = 0;
                if (int.TryParse(context.Request["scriptID"], out scriptID))
                {
                    string newName = context.Request["name"];
                    string existingName = context.Request["existingName"];
                    Regex myRegex = new Regex(@"^[\w]+$");
                    if (myRegex.IsMatch(newName))
                    {
                        Dictionary<int, string> scripts = ScriptManager.GetScripts(ScriptType.Css);
                        if (!scripts.ContainsValue(newName))
                        {
                            Script s = ScriptManager.GetScript(scriptID);
                            s.Name = newName;
                            ScriptManager.Save(s);
                            output = "Successfully renamed CSS script \"" + existingName + "\" to \"" + newName + "\".";
                        }
                        else
                        {
                            output = "Script update failed: Another CSS script with this name already exists.";
                        }
                    }
                    else
                    {
                        output = "Script update failed: Please use only alphanumeric characters.";
                    }
                }
                else
                {
                    output = "Script update failed: Script identifier parameter not valid.";
                }
            }
            else
            {
                output = "Script update failed: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>";
            }

            context.Response.Write(output);
        }

        /// <summary>
        /// Handles the request to select a list of style sheets.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void LoadCssScripts(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load CSS: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                Dictionary<int, string> dic = ScriptManager.GetScripts(ScriptType.Css);
                List<string> json = new List<string>();
                foreach (KeyValuePair<int, string> kvp in dic)
                {
                    json.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                context.Response.Write("[" + string.Join(",", json.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Loads cascading style sheet scripts.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadCssScript(HttpContext context)
        {
            int cssId = 0;
            if (int.TryParse(context.Request.QueryString["ID"], out cssId))
            {
                Script script = ScriptManager.GetScript(cssId);
                if (script.ScriptType == ScriptType.Css)
                {
                    context.Response.Clear();
                    context.Response.ContentType = "text/css";
                    context.Response.Charset = Encoding.UTF8.WebName;
                    context.Response.Write(script.ScriptText);
                }
                else
                {
                    context.Response.Clear();
                    context.Response.ContentType = "text/css";
                    context.Response.Charset = Encoding.UTF8.WebName;
                    context.Response.Write("/* Empty File */");
                }
            }
            else
            {
                context.Response.Clear();
                context.Response.ContentType = "text/css";
                context.Response.Charset = Encoding.UTF8.WebName;
                context.Response.Write("/* Empty File */");
            }
        }
        #endregion

        #region JavaScript
        /// <summary>
        /// Handles the request to update a javascript.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdateJS(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to update JavaScript: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int scriptId = 0;
            if (!int.TryParse(context.Request["jsID"], out scriptId))
            {
                output.Add("Failed to update JavaScript: Invalid jsID parameter.");
            }

            if (output.Count == 0)
            {
                Script s = ScriptManager.GetScript(scriptId);
                s.ScriptText = context.Request["content"];
                ScriptManager.Save(s);
                output.Add("Successfully updated JavaScript.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to select javascript info for editing.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void EditJS(HttpContext context)
        {
            bool isAdmin = false;
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load JavaScript: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
            else
            {
                isAdmin = true;
            }

            int scriptId = 0;
            if (!int.TryParse(context.Request["jsID"], out scriptId))
            {
                output.Add("Failed to load JavaScript: Invalid jsID parameter.");
            }

            if (output.Count == 0)
            {
                Script s = ScriptManager.GetScript(scriptId);
                List<string> pages = ScriptManager.GetPages(s);
                string[] jsonPages = new string[pages.Count];
                for (int i = 0; i < pages.Count; i++)
                {
                    jsonPages[i] = "{\"Name\": \"" + pages[i] + "\"}";
                }

                context.Response.Write("[{ \"IsAdmin\": \"" + (isAdmin ? "1" : "0") + "\", \"Content\": \"" + EscapeJson(s.ScriptText) + "\", \"Pages\" : [" + string.Join(", ", jsonPages) + "]}]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request to add a javascript.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddJS(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to create JavaScript: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to create JavaScript: Invalid name parameter.");
            }

            Dictionary<int, string> scripts = ScriptManager.GetScripts(ScriptType.JS);
            if (scripts.ContainsValue(context.Request["name"]))
            {
                output.Add("Failed to create JavaScript: JavaScript name already exists.");
            }

            if (output.Count == 0)
            {
                Script s = new Script();
                s.Name = context.Request["name"];
                s.ScriptType = ScriptType.JS;
                ScriptManager.SaveAs(s);
                output.Add("Successfully created JavaScript.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to rename a javascript.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void RenameJS(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to rename JavaScript: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int scriptId = 0;
            if (!int.TryParse(context.Request["scriptID"], out scriptId))
            {
                output.Add("Failed to rename JavaScript: Invalid scriptID parameter.");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to rename JavaScript: Invalid name parameter.");
            }

            Dictionary<int, string> scripts = ScriptManager.GetScripts(ScriptType.JS);
            if (scripts.ContainsValue(context.Request["name"]))
            {
                output.Add("Failed to rename JavaScript: JavaScript name already exists.");
            }

            if (output.Count == 0)
            {
                Script s = ScriptManager.GetScript(scriptId);
                s.Name = context.Request["name"];
                ScriptManager.Save(s);
                output.Add("Successfully renamed JavaScript.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to select a list of javascripts.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void LoadJSScripts(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load JavaScripts: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                Dictionary<int, string> dic = ScriptManager.GetScripts(ScriptType.JS);
                List<string> json = new List<string>();
                foreach (KeyValuePair<int, string> kvp in dic)
                {
                    json.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", kvp.Key, kvp.Value));
                }

                context.Response.Write("[" + string.Join(",", json.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Loads javascript scripts.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadJS(HttpContext context)
        {
            int scriptId = 0;
            if (int.TryParse(context.Request.QueryString["ID"], out scriptId))
            {
                Script script = ScriptManager.GetScript(scriptId);
                if (script.ScriptType == ScriptType.JS)
                {
                    context.Response.Clear();
                    context.Response.ContentType = "text/javascript";
                    context.Response.Charset = Encoding.UTF8.WebName;
                    context.Response.Write(script.ScriptText);
                }
                else
                {
                    context.Response.Clear();
                    context.Response.ContentType = "text/javascript";
                    context.Response.Charset = Encoding.UTF8.WebName;
                    context.Response.Write("/* Empty File */");
                }
            }
            else
            {
                context.Response.Clear();
                context.Response.ContentType = "text/javascript";
                context.Response.Charset = Encoding.UTF8.WebName;
                context.Response.Write("/* Empty File */");
            }
        }
        #endregion

        #region Shared CSS and Script Methods
        /// <summary>
        /// Handles the request to delete a script.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void DeleteScript(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to delete script: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int scriptId = 0;
            if (!int.TryParse(context.Request["scriptID"], out scriptId))
            {
                output.Add("Failed to delete script: Invalid scriptID parameter.");
            }

            if (output.Count == 0)
            {
                Script s = ScriptManager.GetScript(scriptId);
                ScriptManager.Delete(s);
                output.Add("Successfully deleted script.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Template Methods
        /// <summary>
        /// Handles the request to add a new header template script to the application.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddTemplate(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to create template: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to create template: Invalid name parameter.");
            }

            int templateArea = 5;
            if (!int.TryParse(context.Request["area"], out templateArea))
            {
                output.Add("Failed to create template: Invalid area parameter.");
            }
            else if (templateArea < 0 || templateArea > 4)
            {
                output.Add("Failed to create template: Invalid area parameter.");
            }
            else
            {
                List<Template> templates = TemplateManager.GetTemplatesWithoutText((TemplateArea)templateArea);
                for (int i = 0; i < templates.Count; i++)
                {
                    if (templates[i].Name == context.Request["name"])
                    {
                        output.Add("Failed to create template: Template name already exists.");
                        break;
                    }
                }
            }

            if (output.Count == 0)
            {
                Template t = new Template();
                t.Name = context.Request["name"];
                t.Area = (TemplateArea)templateArea;
                TemplateManager.SaveAs(t);
                output.Add("Successfully created template.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to list the template objects associated with this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadTemplates(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load templates: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int templateArea = 5;
            if (!int.TryParse(context.Request["area"], out templateArea))
            {
                output.Add("Failed to load templates: Invalid area parameter.");
            }
            else if (templateArea < 0 || templateArea > 4)
            {
                output.Add("Failed to load templates: Invalid area parameter.");
            }
            
            if (output.Count == 0)
            {
                List<Template> templates = TemplateManager.GetTemplatesWithoutText((TemplateArea)templateArea);
                List<string> json = new List<string>();
                for (int i = 0; i < templates.Count; i++)
                {
                    json.Add(string.Format(CultureInfo.InvariantCulture, "{{\"ID\" : \"{0}\",\"Name\" : \"{1}\"}}", templates[i].Id, templates[i].Name));
                }

                context.Response.Write("[" + string.Join(",", json.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }
        
        /// <summary>
        /// Handles the request to update template section script content.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdateTemplate(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to update template: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int templateId = 0;
            if (!int.TryParse(context.Request["templateID"], out templateId))
            {
                output.Add("Failed to update template: Invalid templateID parameter.");
            }

            if (output.Count == 0)
            {
                Template t = TemplateManager.GetTemplate(templateId);
                t.TemplateText = context.Request["content"];
                TemplateManager.Save(t);
                output.Add("Successfully updated template.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        
        /// <summary>
        /// Handles the request to delete template header or footer objects from this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void DeleteTemplate(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to delete template: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int templateId = 0;
            if (!int.TryParse(context.Request["templateID"], out templateId))
            {
                output.Add("Failed to delete template: Invalid templateID parameter.");
            }

            if (output.Count == 0)
            {
                Template t = TemplateManager.GetTemplate(templateId);
                TemplateManager.Delete(t);
                output.Add("Successfully deleted template.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request for a template footer object's contents for editing.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void EditTemplate(HttpContext context)
        {
            bool isAdmin = false;
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to load template: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
            else
            {
                isAdmin = true;
            }

            int templateId = 0;
            if (!int.TryParse(context.Request["templateID"], out templateId))
            {
                output.Add("Failed to load template: Invalid templateID parameter.");
            }

            if (output.Count == 0)
            {
                Template t = TemplateManager.GetTemplate(templateId);
                List<string> pages = TemplateManager.GetPages(t);
                string[] jsonPages = new string[pages.Count];
                for (int i = 0; i < pages.Count; i++)
                {
                    jsonPages[i] = "{\"Name\": \"" + pages[i] + "\"}";
                }

                context.Response.Write("[{ \"IsAdmin\": \"" + (isAdmin ? "1" : "0") + "\", \"Content\": \"" + EscapeJson(t.TemplateText) + "\", \"Pages\" : [" + string.Join(", ", jsonPages) + "]}]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request to rename a template object in this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void RenameTemplate(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to rename template: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to rename template: Invalid name parameter.");
            }

            Template t = null;
            int templateId = 0;
            if (!int.TryParse(context.Request["templateID"], out templateId))
            {
                output.Add("Failed to rename template: Invalid templateID parameter.");
            }
            else if (output.Count == 0)
            {
                t = TemplateManager.GetTemplate(templateId);
                List<Template> templates = TemplateManager.GetTemplatesWithoutText(t.Area);
                for (int i = 0; i < templates.Count; i++)
                {
                    if (templates[i].Name == context.Request["name"])
                    {
                        output.Add("Failed to rename template: Template name already exists.");
                        break;
                    }
                }
            }

            if (output.Count == 0)
            {
                t.Name = context.Request["name"];
                TemplateManager.Save(t);
                output.Add("Successfully renamed template.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Profile
        /// <summary>
        /// Handles a request to list the users associated with this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadUsers(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load profiles: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                UserProfile userProfile = null;
                List<string> userProfileRoles = new List<string>();
                Dictionary<int, string> profiles = UserProfileManager.GetUsersIdsAndUserNames();
                List<string> jsonProfiles = new List<string>(profiles.Count);
                foreach (KeyValuePair<int, string> kvp in profiles)
                {
                    userProfile = UserProfileManager.GetUserProfile(kvp.Key);
                    userProfileRoles = UserProfileManager.GetRoles(userProfile);
                    jsonProfiles.Add(string.Format(CultureInfo.InvariantCulture, "{{\"UserID\" : \"{0}\",\"UserName\" : \"{1}\", \"SiteAdministrator\": \"{2}\", \"ContentManager\": \"{3}\", \"ContentProvider\": \"{4}\"}}", new object[] { kvp.Key, kvp.Value, userProfileRoles.Contains("Site Administrator") ? 1 : 0, userProfileRoles.Contains("Content Manager") ? 1 : 0, userProfileRoles.Contains("Content Provider") ? 1 : 0 }));
                }
                
                context.Response.Write("[" + string.Join(", ", jsonProfiles) + "]"); 
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request to delete user objects from this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void DeleteUser(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("Failed to delete profile: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int profileId = 0;
            if (!int.TryParse(context.Request["userID"], out profileId))
            {
                output.Add("Failed to delete profile: Invalid userID parameter.");
            }

            if (output.Count == 0)
            {
                UserProfile profile = UserProfileManager.GetUserProfile(profileId);
                UserProfileManager.Delete(profile);
                output.Add("Successfully deleted profile.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to update a user.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void UpdateUser(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("<li>You have insufficient privileges to perform this action.</li>");
            }

            int userId = 0;
            if (!int.TryParse(context.Request["userID"], out userId))
            {
                output.Add("<li>User ID parameter invalid. It must be an integer.</li>");
            }

            if (string.IsNullOrEmpty(context.Request["username"]))
            {
                output.Add("<li>User Name parameter invalid. It was not found.</li>");
            }

            if (string.IsNullOrEmpty(context.Request["password"]))
            {
                output.Add("<li>Password parameter invalid. It was not found.</li>");
            }

            if (output.Count == 0)
            {
                UserProfile profile = UserProfileManager.GetUserProfile(userId);
                profile.UserName = context.Request["username"];
                profile.SetPassword(UserProfileManager.EncodePassword(context.Request["password"]));
                UserProfileManager.Save(profile);
                UserProfileManager.ClearRoles(profile);
                List<Role> roles = RoleManager.GetRoles();
                if (context.Request["SiteAdministrator"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Site Administrator")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }

                if (context.Request["ContentManager"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Content Manager")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }

                if (context.Request["ContentProvider"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Content Provider")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }

                output.Add("Successfully updated user.");
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to insert a user.
        /// </summary>
        /// <param name="context">The HttpContext sent with the request.</param>
        private void AddUser(HttpContext context)
        {
            List<string> output = new List<string>();
            if (!UserProfileManager.GetRoles(UserProfileManager.Current).Contains("Site Administrator"))
            {
                output.Add("You have insufficient privileges to perform this action.");
            }

            if (string.IsNullOrWhiteSpace(context.Request["username"]))
            {
                output.Add("User Name parameter invalid. It was not found.");
            }

            if (string.IsNullOrWhiteSpace(context.Request["password"]))
            {
                output.Add("Password parameter invalid. It was not found.");
            }

            if (output.Count == 0)
            {
                UserProfile profile = new UserProfile();
                profile.UserName = context.Request["username"];
                profile.SetPassword(UserProfileManager.EncodePassword(context.Request["password"]));
                profile = UserProfileManager.SaveAs(profile);
                UserProfileManager.ClearRoles(profile);
                List<Role> roles = RoleManager.GetRoles();
                if (context.Request["SiteAdministrator"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Site Administrator")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }

                if (context.Request["ContentManager"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Content Manager")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }

                if (context.Request["ContentProvider"] == "1")
                {
                    for (int i = 0; i < roles.Count; i++)
                    {
                        if (roles[i].Name == "Content Provider")
                        {
                            UserProfileManager.AddRole(profile, roles[i]);
                        }
                    }
                }
                
                output.Add("Successfully added user.");
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Roles
        /// <summary>
        /// Handles a request to list the roles associated with this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadRoles(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load roles: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<Role> roleCollection = RoleManager.GetRoles();
                for (int i = 0; i < roleCollection.Count; i++)
                {
                    output.Add("{\"RoleID\":\"" + roleCollection[i].Id + "\", \"RoleName\":\"" + EscapeJson(roleCollection[i].Name) + "\"}");
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }
        #endregion

        #region Asset
        /// <summary>
        /// Handles a request to rename a file object in this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void RenameFile(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to rename asset: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[.\w]+$"))
            {
                output.Add("Failed to rename asset: Invalid name parameter.");
            }

            string path = string.IsNullOrEmpty(context.Request["path"]) ? string.Empty : context.Request["path"] + "/";
            if (AssetManager.GetFileByVirtualPath(path + context.Request["name"]) != null)
            {
                output.Add("Failed to rename asset: Asset name already exists.");
            }

            if (FileTypeManager.GetFileTypeByExtension(context.Request["name"].Substring(context.Request["name"].LastIndexOf(".", StringComparison.Ordinal) + 1)) == null)
            {
                output.Add("Failed to rename asset: This file type is not hosted.");
            }

            if (output.Count == 0)
            {
                Asset f = AssetManager.GetFileByVirtualPath(context.Request["existingPath"]);
                f.VirtualPath = path + context.Request["name"];
                AssetManager.Save(f);
                output.Add("Successfully renamed asset.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to delete a file object from this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void DeleteFile(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to delete asset: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                Asset f = AssetManager.GetFileByVirtualPath(context.Request["path"]);
                FileInfo fi = new FileInfo(BusinessLogic.Environment.StaticFilesDirectory + f.FilePath);
                fi.Delete();
                AssetManager.Delete(f);
                output.Add("Successfully deleted asset.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Uploads static files from Uploadify (flash multi-upload jQuery extension)
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void Upload(HttpContext context)
        {
            bool goodToUpload = true;
            int userID = 0;
            HttpPostedFile file = context.Request.Files["Filedata"];
            string filepath = context.Request["strFilepath"];
            string cookie = context.Request["strCookie"];
            bool unzip = context.Request["unzip"] == "yes" ? true : false;
            HttpCookie encoded = new HttpCookie("Lidocaine", cookie);
            HttpCookie decoded = HttpSecureCookie.Decode(encoded);
            userID = Convert.ToInt32(decoded.Values["ID"], CultureInfo.InvariantCulture);
            UserProfile currentUser = UserProfileManager.GetUserProfile(userID);
            List<string> roles = UserProfileManager.GetRoles(currentUser);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager") && !roles.Contains("Content Provider"))
            {
                goodToUpload = false;
                context.Response.Write("Upload Failed on " + file.FileName + ":  Upload Permission Denied.");
            }

            if (goodToUpload && unzip && file.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
            {
                DirectoryInfo di = new DirectoryInfo(BusinessLogic.Environment.StaticFilesDirectory + @"\temp");
                if (!di.Exists)
                {
                    di.Create();
                }

                try
                {
                    int i = 0;
                    FileInfo fi = new FileInfo(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + i + file.FileName);
                    while (fi.Exists)
                    {
                        i++;
                        fi = new FileInfo(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + i + file.FileName);
                    }
                    
                    file.SaveAs(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + i + file.FileName);
                    ZipFile z = new ZipFile(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + i + file.FileName);
                    int j = 0;
                    di = new DirectoryInfo(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + j);
                    while (di.Exists)
                    {
                        j++;
                        di = new DirectoryInfo(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + j);
                    }

                    z.ExtractAll(BusinessLogic.Environment.StaticFilesDirectory + @"\temp\" + j);
                    context.Response.Write(this.RecursiveFileImport(di, filepath));
                    z.Dispose();
                    di.Delete(true);
                    fi.Delete();
                }
                catch (Exception ex)
                {
                    context.Response.Write("Upload Failed on " + file.FileName + ": " + ex.Message.ToString(CultureInfo.InvariantCulture));
                }
            }
            else if (goodToUpload)
            {
                if (!Regex.IsMatch(file.FileName, @"^[\w.]+$"))
                {
                    goodToUpload = false;
                    context.Response.Write("Upload Failed on " + file.FileName + ":  Please use only alphanumeric characters, \"_\" and \".\".");
                }

                FileType filetype = FileTypeManager.GetFileTypeByExtension(file.FileName.Substring(file.FileName.LastIndexOf(".", StringComparison.Ordinal) + 1));
                if (filetype == null)
                {
                    goodToUpload = false;
                    context.Response.Write("Upload Failed on " + file.FileName + ":  This file type is not hosted.");
                }

                if (!string.IsNullOrEmpty(filepath))
                {
                    filepath += "/";
                }

                Asset f = AssetManager.GetFileByVirtualPath(filepath + file.FileName);
                if (f != null)
                {
                    goodToUpload = false;
                    context.Response.Write("Upload Failed on " + file.FileName + ":  Another file with the same name already exists.");
                }

                if (goodToUpload)
                {
                    f = AssetManager.New();
                    f.VirtualPath = filepath + file.FileName;
                    f.FileType = filetype;
                    AssetManager.SaveAs(f);

                    try
                    {
                        file.SaveAs(BusinessLogic.Environment.StaticFilesDirectory + @"\" + f.Id + "." + f.FileType.Extension);
                        context.Response.Write("Upload Successful on " + file.FileName + ".");
                    }
                    catch (Exception ex)
                    {
                        AssetManager.Delete(f);
                        context.Response.Write("Upload Failed on " + file.FileName + ": " + ex.Message.ToString(CultureInfo.InvariantCulture));
                    }
                }
            }
        }

        /// <summary>
        /// Recursively enters zipped document contents into the database.
        /// </summary>
        /// <param name="di">The current directory to import.</param>
        /// <param name="filepath">The current location for imports to be placed.</param>
        /// <returns>A string representing the status of the file import.</returns>
        private string RecursiveFileImport(DirectoryInfo di, string filepath)
        {
            StringBuilder output = new StringBuilder();
            if (!string.IsNullOrEmpty(filepath))
            {
                filepath += "/";
            }

            // import directories
            Folder folder;
            DirectoryInfo[] childDirectories = di.GetDirectories();
            for (int i = 0; i < childDirectories.Length; i++)
            {
                folder = FolderManager.GetFolderByPath(filepath + childDirectories[i].Name);
                if (folder == null)
                {
                    folder = new Folder();
                    folder.Path = filepath + childDirectories[i].Name;
                    FolderManager.SaveAs(folder);
                    output.Append(this.RecursiveFileImport(childDirectories[i], folder.Path) + "<br />");
                }
                else
                {
                    output.Append("Upload Failed on " + folder.Path + "/" + childDirectories[i].Name + ": folder already exists.<br />");
                }
            }

            // import files
            bool goodToUpload = true;
            FileInfo[] childFiles = di.GetFiles();
            for (int i = 0; i < childFiles.Length; i++)
            {
                if (!Regex.IsMatch(childFiles[i].Name, @"^[\w.]+$"))
                {
                    goodToUpload = false;
                    output.Append("Upload Failed on " + childFiles[i].Name + ":  Please use only alphanumeric characters, \"_\" and \".\".<br />");
                }

                FileType filetype = FileTypeManager.GetFileTypeByExtension(childFiles[i].Extension.TrimStart('.'));
                if (filetype == null)
                {
                    goodToUpload = false;
                    output.Append("Upload Failed on " + childFiles[i].Name + ":  This file type is not hosted.<br />");
                }

                Asset f = AssetManager.GetFileByVirtualPath(filepath + childFiles[i].Name);
                if (f != null)
                {
                    goodToUpload = false;
                    output.Append("Upload Failed on " + childFiles[i].Name + ":  Another file with the same name already exists.<br />");
                }

                if (goodToUpload)
                {
                    f = AssetManager.New();
                    f.VirtualPath = filepath + childFiles[i].Name;
                    f.FileType = filetype;
                    AssetManager.SaveAs(f);

                    try
                    {
                        childFiles[i].CopyTo(BusinessLogic.Environment.StaticFilesDirectory + @"\" + f.Id + "." + f.FileType.Extension);
                        output.Append("Upload Successful on " + childFiles[i].Name + ".<br />");
                    }
                    catch (Exception ex)
                    {
                        AssetManager.Delete(f);
                        output.Append("Upload Failed on " + childFiles[i].Name + ": " + ex.Message.ToString(CultureInfo.InvariantCulture) + "<br />");
                    }
                }
            }

            return output.ToString();
        }
        #endregion

        #region PageLayout
        /// <summary>
        /// Handles the request to rename a page object in this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void RenamePage(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to rename page: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to rename page: Invalid name parameter.");
            }

            string path = string.IsNullOrEmpty(context.Request["path"]) ? string.Empty : context.Request["path"] + "/";
            if (PageLayoutManager.GetPageLayout(path + context.Request["name"] + ".aspx") != null)
            {
                output.Add("Failed to delete page: PageLayout already exists at this path.");
            }
            
            if (output.Count == 0)
            {
                PageLayout page = PageLayoutManager.GetPageLayout(context.Request["existingPath"]);
                page.Path = path + context.Request["name"] + ".aspx";
                PageLayoutManager.Save(page);
                output.Add("Successfully renamed page.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }
            
            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to delete a page object from this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void DeletePage(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to delete page: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                PageLayoutManager.Delete(PageLayoutManager.GetPageLayout(context.Request["path"]));
                output.Add("Successfully deleted page.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to add a page object to this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void AddPage(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to create page: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to create page: Invalid name parameter.");
            }

            string path = string.IsNullOrEmpty(context.Request["path"]) ? string.Empty : context.Request["path"] + "/";
            if (PageLayoutManager.GetPageLayout(path + context.Request["name"] + ".aspx") != null)
            {
                output.Add("Failed to delete page: PageLayout already exists at this path.");
            }

            if (output.Count == 0)
            {
                PageLayout page = PageLayoutManager.New();
                page.Path = path + context.Request["name"] + ".aspx";
                PageLayoutManager.SaveAs(page);
                output.Add("Successfully created page.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }
            
            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Folder
        /// <summary>
        /// Handles the request to rename a folder object in this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void RenameFolder(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to rename folder: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (string.IsNullOrWhiteSpace(context.Request["name"]) || !Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to rename folder: Invalid name parameter.");
            }

            string path = string.IsNullOrEmpty(context.Request["path"]) ? string.Empty : context.Request["path"] + "/";
            if (FolderManager.GetFolderByPath(path + context.Request["name"]) != null)
            {
                output.Add("Failed to rename folder: Folder already exists at this path.");
            }

            if (output.Count == 0)
            {
                Folder folder = FolderManager.GetFolderByPath(context.Request["existingPath"]);
                folder.Path = path + context.Request["name"];
                FolderManager.Save(folder);
                output.Add("Successfully renamed folder.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to delete a folder object and all of its child objects from this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void DeleteFolder(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to delete folder: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            Folder folder = FolderManager.GetFolderByPath(context.Request["path"]);
            if (folder == null)
            {
                output.Add("Failed to delete folder: Invalid path parameter.");
            }

            if (output.Count == 0)
            {
                FolderManager.Delete(folder);
                output.Add("Successfully deleted folder.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }

        /// <summary>
        /// Handles the request to add a folder object to this application.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void AddFolder(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to create folder: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (!Regex.IsMatch(context.Request["name"], @"^[\w]+$"))
            {
                output.Add("Failed to create folder: Invalid name parameter.");
            }

            string path = string.IsNullOrEmpty(context.Request["path"]) ? string.Empty : context.Request["path"] + "/";
            if (FolderManager.GetFolderByPath(path + context.Request["name"]) != null)
            {
                output.Add("Failed to create folder: Folder name already exists.");
            }

            if (output.Count == 0)
            {
                Folder f = new Folder();
                f.Path = path + context.Request["name"];
                FolderManager.SaveAs(f);
                output.Add("Successfully created folder.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Administration and Permissions
        /// <summary>
        /// Handles the request to list the child files and directories of a virtual path.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void LoadExplorer(HttpContext context)
        {
            List<string> output = new List<string>();
            bool isAdmin = false;
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load explorer: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }
            else
            {
                isAdmin = true;
            }

            if (output.Count == 0)
            {
                List<ExplorerItem> items = Explorer.Load(context.Request["path"], context.Request["depth"]);
                for (int i = 0; i < items.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{\"Path\":\"{0}\",\"Source\":\"{1}\"}}", new object[] { items[i].Path, (int)items[i].Source }));
                }

                context.Response.Write("[{ \"N\": \"" + BusinessLogic.Environment.Domain + "\", \"IsAdmin\": \"" + (isAdmin ? "1" : "0") + "\", \"Items\" : [" + string.Join(", ", output.ToArray()) + "]}]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }
        
        /// <summary>
        /// Handles the request to add permissions to a folder, page, or file object.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void AddPermissions(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to create permissions: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int allowID = 0;
            if (!int.TryParse(context.Request["AllowID"], out allowID))
            {
                output.Add("Failed to create permissions: Invalid AllowID parameter.");
            }

            int allowType = 0;
            if (!int.TryParse(context.Request["AllowType"], out allowType))
            {
                output.Add("Failed to create permissions: Invalid AllowType parameter.");
            }

            if (output.Count == 0)
            {
                string strItemPath = context.Request["ItemPath"];
                int itemID = 0;
                int itemType = 0;

                if (strItemPath.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))
                {
                    itemType = (int)Source.Page;
                    PageLayout page = PageLayoutManager.GetPageLayout(strItemPath);
                    itemID = page.Id;
                }
                else if (strItemPath.Contains("."))
                {
                    itemType = (int)Source.File;
                    Asset f = AssetManager.GetFileByVirtualPath(strItemPath);
                    itemID = f.Id;
                }
                else
                {
                    itemType = (int)Source.Folder;
                    Folder folder = FolderManager.GetFolderByPath(strItemPath);
                    itemID = folder.Id;
                }

                AuthorizationManager.AddPermission((Source)itemType, itemID, (PermissionAllowType)allowType, allowID);
                output.Add("Successfully created permissions.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        
        /// <summary>
        /// Handles the request for the permissions on a folder object.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void GetFolderPermissions(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load folder permissions: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<Permission> permissions = FolderManager.GetPermissionsWithRoleInfo(context.Request["FolderPath"]);
                for (int i = 0; i < permissions.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{ \"Name\": \"{0}\", \"PermissionID\": \"{1}\" }}", new object[] { permissions[i].Name, permissions[i].Id }));
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }
        
        /// <summary>
        /// Handles the request for the permissions on a page object.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void GetPagePermissions(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load page permissions: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<Permission> permissions = PageLayoutManager.GetPermissionsWithRoleInfo(context.Request["PagePath"]);
                for (int i = 0; i < permissions.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{ \"Name\": \"{0}\", \"PermissionID\": \"{1}\" }}", new object[] { permissions[i].Name, permissions[i].Id }));
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request for the permissions on a file object.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void GetFilePermissions(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to load asset permissions: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            if (output.Count == 0)
            {
                List<Permission> permissions = AssetManager.GetPermissionsWithRoleInfo(context.Request["VirtualPath"]);
                for (int i = 0; i < permissions.Count; i++)
                {
                    output.Add(string.Format(CultureInfo.InvariantCulture, "{{ \"Name\": \"{0}\", \"PermissionID\": \"{1}\" }}", new object[] { permissions[i].Name, permissions[i].Id }));
                }

                context.Response.Write("[" + string.Join(", ", output.ToArray()) + "]");
            }
            else
            {
                context.Response.StatusCode = 500;
                context.Response.Write(string.Join("</li><li>", output.ToArray()));
            }
        }

        /// <summary>
        /// Handles the request to remove permissions to access an object from the web.
        /// </summary>
        /// <param name="context">The current HTTP context object.</param>
        private void RemovePermissions(HttpContext context)
        {
            List<string> output = new List<string>();
            List<string> roles = UserProfileManager.GetRoles(UserProfileManager.Current);
            if (!roles.Contains("Site Administrator") && !roles.Contains("Content Manager"))
            {
                output.Add("Failed to remove permissions: User not authorized." + " <a href=\"" + BusinessLogic.Environment.LogOnUrl.OriginalString + "?ReturnUrl=/cms/\">" + Strings.ClickHereToReauthenticate + "</a>");
            }

            int permissionId = 0;
            if (!int.TryParse(context.Request["PermissionID"], out permissionId))
            {
                output.Add("Failed to remove permissions: Invalid PermissionID parameter.");
            }

            if (output.Count == 0)
            {
                AuthorizationManager.RemovePermission(permissionId);
                output.Add("Successfully removed permissions.");
            }
            else
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Write(string.Join("</li><li>", output.ToArray()));
        }
        #endregion

        #region Request Handler
        /// <summary>
        /// Loads the dictionary mapping input strings to their associated method.
        /// </summary>
        /// <returns>A dictionary of strings mapped to methods.</returns>
        private Dictionary<string, Action<HttpContext>> GetHandlers()
        {
            Dictionary<string, Action<HttpContext>> d = new Dictionary<string, Action<HttpContext>>
            {
                { "DeleteFileType", this.DeleteFileType },
                { "AddFileType", this.AddFileType },
                { "UpdateFileType", this.UpdateFileType },
                { "LoadFileTypes", this.LoadFileTypes },
                { "UpdatePageSettingsTitle", this.UpdatePageSettingsTitle },
                { "UpdatePageSettingsHeader", this.UpdatePageSettingsHeader },
                { "UpdatePageSettingsFooter", this.UpdatePageSettingsFooter },
                { "UpdatePageSettingsLeftNav", this.UpdatePageSettingsLeftNav },
                { "UpdatePageSettingsRightCol", this.UpdatePageSettingsRightCol },
                { "UpdatePageSettingsTopNav", this.UpdatePageSettingsTopNav },
                { "UpdatePageSettingsCSS", this.UpdatePageSettingsCss },
                { "UpdatePageSettingsJS", this.UpdatePageSettingsJS },
                { "UpdatePageSettingsContentVersion", this.UpdatePageSettingsContentVersion },
                { "EditPageSettings", this.EditPageSettings },
                { "SaveAndPublishPage", this.SaveAndPublishPage },
                { "SavePage", this.SavePage },
                { "EditPage", this.EditPage },
                { "AddMainColumnDeveloperControl", this.AddMainColumnDeveloperControl },
                { "DeleteMainColumnDeveloperControl", this.DeleteMainColumnDeveloperControl },
                { "LoadMainColumnDeveloperControls", this.LoadMainColumnDeveloperControls },
                { "UpdateJs", this.UpdateJS },
                { "EditJs", this.EditJS },
                { "AddJs", this.AddJS },
                { "DeleteJs", this.DeleteScript },
                { "RenameJs", this.RenameJS },
                { "LoadJs", this.LoadJSScripts },
                { "UpdateCss", this.UpdateCss },
                { "EditCss", this.EditCss },
                { "AddCss", this.AddCss },
                { "DeleteCss", this.DeleteScript },
                { "RenameCss", this.RenameCss },
                { "LoadCss", this.LoadCssScripts },
                { "UpdateTemplate", this.UpdateTemplate },
                { "EditTemplate", this.EditTemplate },
                { "AddTemplate", this.AddTemplate },
                { "RenameTemplate", this.RenameTemplate },
                { "LoadTemplates", this.LoadTemplates },
                { "DeleteTemplate", this.DeleteTemplate },
                { "LoadUsers", this.LoadUsers },
                { "DeleteUser", this.DeleteUser },
                { "UpdateUser", this.UpdateUser },
                { "AddUser", this.AddUser },
                { "LoadRoles", this.LoadRoles },
                { "RenameFile", this.RenameFile },
                { "RenamePage", this.RenamePage },
                { "RenameFolder", this.RenameFolder },
                { "DeleteFile", this.DeleteFile },
                { "DeletePage", this.DeletePage },
                { "DeleteFolder", this.DeleteFolder },
                { "AddPage", this.AddPage },
                { "AddFolder", this.AddFolder },
                { "LoadExplorer", this.LoadExplorer },
                { "AddPermissions", this.AddPermissions },
                { "GetFolderPermissions", this.GetFolderPermissions },
                { "GetPagePermissions", this.GetPagePermissions },
                { "GetFilePermissions", this.GetFilePermissions },
                { "RemovePermissions", this.RemovePermissions },
                { "LoadCSS", this.LoadCssScript },
                { "LoadJS", this.LoadJS },
                { "LoadDeveloperControls", this.LoadDeveloperControls },
                { "LoadDeveloperControlDescription", this.LoadDeveloperControlDescription },
                { "Upload", this.Upload }
            };

            return d;
        }
        #endregion
    }
}